home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
pcr
/
pcr4_4.lha
/
DIST
/
boot
/
CommandLoop.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-17
|
28KB
|
1,131 lines
/* begincopyright
Copyright (c) 1988 Xerox Corporation. All rights reserved.
Use and copying of this software and preparation of derivative works based
upon this software are permitted. Any distribution of this software or
derivative works must comply with all applicable United States export
control laws. This software is made available AS IS, and Xerox Corporation
makes no warranty about the software, its performance or its conformity to
any specification. Any person obtaining a copy of this software is requested
to send their name and post office or electronic mail address to
PCRCoordinator.pa@xerox.com, or to:
PCR Coordinator
Xerox PARC
3333 Coyote Hill Rd.
Palo Alto, CA 94304
endcopyright */
/*
* CommandLoop.c
*
* Demers, January 17, 1991 4:59:36 pm PST
*
*/
#include <xr/Threads.h>
#include <xr/ThreadsBackdoor.h>
#include <xr/UIO.h>
#include <xr/ThreadsMsg.h>
#include <xr/CommandLine.h>
#include <xr/CommandLoop.h>
#include <xr/IncrementalLoad.h>
#include <string.h>
/*DEBUG*/
#include <xr/CommandLinePrivate.h>
XR_CLHandle XR_globalCLHandle = NIL;
XR_CLProcsHandle XR_globalCLProcsHandle = NIL;
#ifdef UNDEFINED
int
XR_UnlinkSymtabFiles()
{
int ans1, ans2;
char name[1024];
XR_ILGetInfoFileName(name);
ans1 = unlink(name);
(void)strcat(name, ".dbx"); /* the same name used in generated XrDBX */
ans2 = unlink(name);
return( (ans1 || ans2) ? -1 : 0 );
}
#endif
/* ??? is the following still needed? ??? */
XR_Pointer
XR_ExtensionFree()
{
}
/*
* recursive command processing
*/
/* top-level call environment */
static XR_CLCallEnv XR_topLevelCLCallEnv = NIL;
XR_CLCallEnv
XR_GetTopLevelCLCallEnv()
{
return XR_topLevelCLCallEnv;
}
XR_CLCallEnv
XR_SetTopLevelCLCallEnv(clceNew)
XR_CLCallEnv clceNew;
{
XR_CLCallEnv clceOld = XR_topLevelCLCallEnv;
XR_topLevelCLCallEnv = clceNew;
return clceOld;
}
/* top-level message sink */
static void
XR_StdOutCLMsgSink(buf, nBytes, self)
char *buf;
int nBytes;
XR_MesaProc self;
{
(void)XR_Write(XR_MSG_STDOUT, buf, nBytes);
}
static struct XR_MesaProcRep XR_stdOutCLMsgSinkRep = {
(XR_UntypedProc)(XR_StdOutCLMsgSink),
(XR_Pointer)(NIL)
};
XR_MesaProc XR_stdOutCLMsgSink = &XR_stdOutCLMsgSinkRep;
/* top-level jmpbuf -- longjmp here returns from CLProc */
XR_JmpBuf
XR_GetTopLevelJumpBuf()
{
XR_CLCallEnv clce = XR_topLevelCLCallEnv;
return ((clce == NIL) ? NIL : &(clce->clce_jmpBuf));
}
/* top-level CL error handler -- if non-nil, called w/result on error */
void
XR_StoreTopLevelCLErrorHandler(mp)
XR_MesaProc mp;
{
XR_CLCallEnv clce = XR_topLevelCLCallEnv;
if( clce != NIL ) clce->clce_handlerProc = mp;
}
static int
XR_IgnoreCLErrorHandler(prevResult, self)
int prevResult;
XR_MesaProc self;
{
return 1;
}
static struct XR_MesaProcRep XR_ignoreCLErrorHandler = {
(XR_UntypedProc)(XR_IgnoreCLErrorHandler),
(XR_Pointer)(NIL)
};
typedef struct XR_CLErrorHandlerDataRep {
XR_CLCallEnv clehd_clce;
int clehd_argc;
char **clehd_argv;
} * XR_CLErrorHandlerData;
static int
XR_CmdCLErrorHandler(prevResult, self)
int prevResult;
XR_MesaProc self;
{
XR_CLErrorHandlerData clehd = (XR_CLErrorHandlerData)(self->mp_x);
XR_ConsoleMsg("CmdCLErrorHandler pr %d\n", prevResult);
return 1;
}
/* command-file indirection */
typedef struct XR_PrePostProcDataRep {
bool pppd_echoing;
bool pppd_abortOnError;
XR_Ticks pppd_whenStarted;
} * XR_PrePostProcData;
static
XR_CLPROC(XR_CLProc_preprocDefault)
{
XR_PrePostProcData pppd = (XR_PrePostProcData)(clce->clce_clientData);
int i;
if( !pppd->pppd_echoing ) {
/* if not echoing, might want to log the commands ... */
for( i = 0; i < argc; i++ ) {
XR_CLLogMsg "%s ", argv[i]);
}
XR_CLLogMsg "\n");
}
pppd->pppd_whenStarted = XR_TicksSinceBoot();
return 0;
}
static struct XR_MesaProcRep XR_preprocDefault = {
(XR_UntypedProc)(XR_CLProc_preprocDefault),
(XR_Pointer)(NIL)
};
static
XR_CLPROC(XR_CLProc_postprocDefault)
{
XR_PrePostProcData pppd = (XR_PrePostProcData)(clce->clce_clientData);
XR_Ticks deltaTicks;
int ans = 1;
if( prevResult <= 0 ) {
XR_CLErrorMsg "%s: failed", argv[0]);
if( prevResult == 0 ) {
XR_CLErrorMsg " (command not found)");
}
if( pppd->pppd_abortOnError ) {
XR_CLErrorMsg" ... aborting\n");
ans = (-1);
} else {
XR_CLErrorMsg " ... continuing\n");
}
}
deltaTicks = XR_TicksSinceBoot() - pppd->pppd_whenStarted + 1;
XR_CLStatsMsg "Elapsed time %d msec\n", XR_TicksToMsec(deltaTicks));
XR_CLLogMsg "\n");
return ans;
}
static struct XR_MesaProcRep XR_postprocDefault = {
(XR_UntypedProc)(XR_CLProc_postprocDefault),
(XR_Pointer)(NIL)
};
static
XR_CLPROC(XR_CLProc_atSign)
{
XR_Fildes fd, pfd;
bool isStdin;
XR_CLHandle h;
struct XR_PrePostProcDataRep pppdNew;
struct XR_CLCallEnvRep clceNew;
int nestedVerbosity;
int applyAns;
if( argc > 2 ) {
XR_CLErrorMsg "%s args: [command_file_name]\n", argv[0]);
return (-1);
}
if( argc > 1 ) {
isStdin = FALSE;
pfd = XR_nullFildes;
fd = XR_Open(argv[1], O_RDONLY, 0);
if( fd == XR_nullFildes ) {
XR_CLErrorMsg "%s: cannot open %s\n", argv[0], argv[1]);
return (-1);
}
(void) XR_SetGetBlocking(fd, XR_UIO_BLOCKING_SOME_DATA); /* default */
XR_CLLogMsg "Reading commands from file %s:\n\n", argv[1]);
} else {
isStdin = TRUE;
pfd = XR_MSG_STDOUT;
fd = XR_MSG_STDIN;
}
h = XR_CLCreateHandleFromFile(fd, pfd);
if( h != NIL ) {
pppdNew.pppd_echoing = (isStdin);
pppdNew.pppd_abortOnError = (!isStdin);
clceNew.clce_h = h;
clceNew.clce_pH = clce->clce_pH;
clceNew.clce_msgSink = clce->clce_msgSink;
nestedVerbosity = *(clce->clce_msgVerbosityP);
clceNew.clce_msgVerbosityP = &nestedVerbosity;
clceNew.clce_handlerProc = NIL;
clceNew.clce_clientData = (XR_Pointer)(&(pppdNew));
(void) XR_SetTopLevelCLCallEnv(&clceNew);
applyAns = XR_CLApply(
&clceNew, &XR_preprocDefault, &XR_postprocDefault );
(void) XR_SetTopLevelCLCallEnv(clce);
(void) XR_CLDestroyHandle(h);
} else {
XR_CLErrorMsg "%s: out of memory\n", argv[0]);
if( !isStdin ) (void) XR_Close(fd);
return (-1);
}
if( !isStdin ) {
(void) XR_Close(fd);
XR_CLLogMsg "\nDone reading commands from file %s\n", argv[1]);
}
return applyAns;
}
/*
* Function call
*/
#define XR_CLLookupFunc(name, externOnly, recentOnly) \
((XR_UntypedProc)(XR_ILLookupFunc((name), (externOnly), (recentOnly)))
#define XR_IL_CALL_FUNC_MAX_ARGC 8
int
XR_CLCallProc(proc, argc, argv, resultP)
XR_Pointer (*proc)();
int argc;
XR_Pointer *argv;
XR_Pointer *resultP;
{
XR_Pointer resultBuf;
# define CALL (*resultP) = (*proc)
if( proc == NIL ) return (-2);
if( resultP == NIL ) resultP = (&resultBuf);
switch(argc) {
case 0: CALL();
break;
case 1: CALL(argv[0]);
break;
case 2: CALL(argv[0], argv[1]);
break;
case 3: CALL(argv[0], argv[1], argv[2]);
break;
case 4: CALL(argv[0], argv[1], argv[2], argv[3]);
break;
case 5: CALL(argv[0], argv[1], argv[2], argv[3],
argv[4]);
break;
case 6: CALL(argv[0], argv[1], argv[2], argv[3],
argv[4], argv[5]);
break;
case 7: CALL(argv[0], argv[1], argv[2], argv[3],
argv[4], argv[5], argv[6]);
break;
case 8: CALL(argv[0], argv[1], argv[2], argv[3],
argv[4], argv[5], argv[6], argv[7]);
break;
# if (XR_IL_CALL_FUNC_MAX_ARGC != 8)
--> fix me! <--
# endif
default:
return (-1);
}
return 0;
}
#undef CALL
static
XR_CLPROC(XR_CLProc_call_procs)
{
bool externOnly;
bool recentOnly;
XR_ILError ile = NIL;
XR_UntypedProc proc;
int i, ans;
char *myRealName = ((char *)(self->mp_x));
if( strcmp(myRealName, "call_procs") == 0 ) {
externOnly = FALSE; recentOnly = TRUE;
} else {
externOnly = FALSE; recentOnly = FALSE;
}
for( i = 1; i < argc; i++ ) {
ile = XR_LockIncrementalLoadState(TRUE);
if( ile != NIL ) {
XR_CLErrorMsg "%s: can't lock loadstate\n", argv[0]);
return (-1);
}
proc = (XR_UntypedProc)
XR_ILLookupProc( argv[i], externOnly, recentOnly);
(void) XR_UnlockIncrementalLoadState();
if( proc == NIL ) {
XR_CLErrorMsg "%s: can't find procedure %s\n", argv[0], argv[i]);
return (-1);
}
XR_CLLogMsg "calling ");
if( externOnly ) { XR_CLLogMsg "extern proc "); }
XR_CLLogMsg "%s() ... ", argv[i]);
ans = XR_CLCallProc( proc, argc-2, argv+2, NIL );
if( ans < 0 ) {
XR_CLErrorMsg "%s: call %s failed\n", argv[0], argv[i]);
return (-1);
}
XR_CLLogMsg "ok\n");
}
return 1;
}
static
XR_CLPROC(XR_CLProc_call)
{
bool externOnly;
bool recentOnly;
XR_ILError ile = NIL;
XR_UntypedProc proc;
int i, ans;
char *myRealName = ((char *)(self->mp_x));
if( argc < 2 ) {
XR_CLErrorMsg "%s args: function_name [arg ...]\n", argv[0]);
return(-1);
}
if( strcmp(myRealName, "call") == 0 ) {
externOnly = FALSE; recentOnly = TRUE;
} else {
externOnly = FALSE; recentOnly = FALSE;
}
ile = XR_LockIncrementalLoadState(TRUE);
if( ile != NIL ) {
XR_CLErrorMsg "%s: can't lock loadstate\n", argv[0]);
return (-1);
}
proc = (XR_UntypedProc) XR_ILLookupProc(argv[1], externOnly, recentOnly);
(void) XR_UnlockIncrementalLoadState();
if( proc == NIL ) {
XR_CLErrorMsg "%s: can't find procedure %s\n", argv[0], argv[1]);
return (-1);
}
XR_CLLogMsg "calling ");
if( externOnly ) { XR_CLLogMsg "extern proc "); }
XR_CLLogMsg "%s (", argv[1]);
for( i = 2; i < argc; i++ ) {
XR_CLLogMsg "%s", argv[i]);
if( (i+1) < argc ) { XR_CLLogMsg ", "); }
}
XR_CLLogMsg ") ... ");
ans = XR_CLCallProc( proc, argc-2, argv+2, NIL );
if( ans < 0 ) {
XR_CLErrorMsg "%s: call %s failed\n", argv[0], argv[1]);
return (-1);
}
XR_CLLogMsg "ok\n");
return 1;
}
/*
* Load / UnixLoad
*/
XR_UntypedProc
XR_CLProcFromPrefixAndFileName(pfx, fn, externOnly, recentOnly)
char *pfx;
char *fn;
bool externOnly;
bool recentOnly;
{
int pfxLen, sfxLen;
char *buf;
char *pl, *pr;
XR_UntypedProc proc = NIL;
if( pfx == NIL ) pfx = "";
pfxLen = strlen(pfx);
if( fn != NIL ) {
if( (pl = strrchr(fn, '/')) != NIL ) { pl++; } else { pl = fn; }
sfxLen = strlen(pl);
if( (pr = strchr(pl, '.')) != NIL ) sfxLen = (pr - pl);
if( (buf = (char *) XR_malloc(pfxLen+1+sfxLen+1)) == NIL ) return;
(void)strcpy(buf, pfx);
(void)strcpy(buf+pfxLen, "_");
(void)strncpy(buf+pfxLen+1, pl, sfxLen);
buf[pfxLen+1+sfxLen] = 0;
proc = (XR_UntypedProc) XR_ILLookupProc( buf, externOnly, recentOnly );
}
if( (proc == NIL) && (pfxLen > 0) && (externOnly || recentOnly) ) {
proc = (XR_UntypedProc) XR_ILLookupProc( pfx, externOnly, recentOnly );
}
return proc;
}
typedef struct XR_PrintUndefinedDataRep {
bool pud_firstEntry;
XR_CLCallEnv pud_clce;
} *XR_PrintUndefinedData;
static bool
XR_PrintUndefinedSymbol(se, clientData)
XR_ILSymEntry se;
XR_Pointer clientData;
{
# define pud ((XR_PrintUndefinedData)(clientData))
XR_CLCallEnv clce = pud->pud_clce;
if( pud->pud_firstEntry ) {
XR_CLErrorMsg "Undefined:\n");
pud->pud_firstEntry = FALSE;
}
XR_CLErrorMsg " %s", se->ilse_name);
if( se->ilse_ilfe != NIL ) {
XR_CLErrorMsg
" (referenced from %s)", se->ilse_ilfe->ilfe_fName);
}
XR_CLErrorMsg "\n");
return TRUE;
}
#undef pud
static void
XR_LoadCommandPatchSizeProc(ilfe, bytes)
XR_ILFileEntry ilfe;
unsigned bytes;
{
ilfe->ilfe_pBytes = bytes;
}
static
XR_CLPROC(XR_CLProc_load)
{
XR_ILError ile = NIL;
XR_ILSymEntry ilse;
int i;
void (*patchSizeProc)() = NIL;
long int patchBytes = 0;
ile = XR_LockIncrementalLoadState(TRUE);
if( ile != NIL ) {
XR_CLErrorMsg "%s: error %d: %s\n",
argv[0], ile->ile_code, ile->ile_msg);
return (-1);
}
for( i = 1; i < argc; i++ ) {
if( (argv[i][0] == '-') && (argv[i][1] == 'p') ) {
patchBytes = atoi(&(argv[i][2]));
if( patchBytes > 0 ) {
patchSizeProc = XR_LoadCommandPatchSizeProc;
} else {
if( patchBytes < 0 )
XR_CLLogMsg "bad flag %s ignored ... ", argv[i]);
patchSizeProc = NIL;
patchBytes = 0;
}
continue;
}
XR_CLLogMsg "loading %s ... ", argv[i]);
ile = XR_ILLoadFile(
/*fName*/ argv[i],
/*fOffset*/ 0,
/*fMagic*/ 0,
/*refProc*/ NIL,
/*refClientData*/ NIL,
/*defProc*/ NIL,
/*defClientData*/ NIL,
/*commonProc*/ NIL,
/*commonClientData*/ NIL,
/*patchSizeProc*/ patchSizeProc,
/*patchSizeClientData*/ patchBytes
);
if( ile != NIL ) {
XR_CLLogMsg "error %d: %s\n", ile->ile_code, ile->ile_msg);
break;
}
XR_CLLogMsg "ok\n");
}
if( ile == NIL ) {
ile = XR_CommitIncrementalLoad();
}
if( ile != NIL ) {
struct XR_PrintUndefinedDataRep pud;
pud.pud_firstEntry = TRUE;
pud.pud_clce = clce;
XR_ILEnumerateUndefinedSyms(
XR_PrintUndefinedSymbol,
((XR_Pointer)(&pud)) );
(void) XR_AbortIncrementalLoad(NIL);
(void) XR_UnlockIncrementalLoadState();
XR_CLErrorMsg "%s: error %d: %s\n",
argv[0], ile->ile_code, ile->ile_msg);
if( i < argc ) XR_CLErrorMsg "\tfile: %s\n", argv[i]);
return (-1);
} else {
(void) XR_UnlockIncrementalLoadState();
return 1;
}
}
static
XR_CLPROC(XR_CLProc_unixload)
{
XR_ILError ile = NIL;
XR_Pointer (*proc)();
int ans, loadAns;
if( argc == 2 ) goto Try;
if( (argc == 3) && (argv[1][0] == '-') && (argv[1][1] == 'p') ) goto Try;
XR_CLErrorMsg "%s args: file_name\n", argv[0]);
return(-1);
Try:
loadAns = XR_CLCallIndirect(clce,
"load_files", argc, argv);
if( loadAns <= 0 ) {
/* already printed:
XR_CLErrorMsg "%s: failed to load %s\n", argv[0], argv[1]); */
return (-1);
}
ile = XR_LockIncrementalLoadState(TRUE);
if( ile != NIL ) {
XR_CLErrorMsg "%s: error %d: %s\n",
argv[0], ile->ile_code, ile->ile_msg);
return (-1);
}
proc = XR_CLProcFromPrefixAndFileName(
"_XR_run", argv[1], FALSE, TRUE );
(void) XR_UnlockIncrementalLoadState();
if( proc != NIL ) {
XR_CLLogMsg "calling run proc ... ");
ans = XR_CLCallProc( proc, 0, NIL, NIL );
if( ans < 0 ) XR_Panic("XR_CLProc_unixload 0");
XR_CLLogMsg "ok\n");
} else {
XR_CLWarningMsg "%s: warning: can't find run proc for %s\n",
argv[0], argv[1] );
}
return 1;
}
/*
* Verbosity control
*/
static
XR_CLPROC(XR_CLProc_msgs)
{
char *myRealName = ((char *)(self->mp_x));
int oldVerbosity, newVerbosity;
switch(argc) {
case 1:
if( strcmp(myRealName, "verbose") == 0 ) {
newVerbosity = XR_VERBOSITY_VERBOSE;
} else if( strcmp(myRealName, "quiet") == 0 ) {
newVerbosity = XR_VERBOSITY_QUIET;
} else {
newVerbosity = XR_VERBOSITY_NORMAL;
}
break;
case 2:
if( strcmpcase(argv[1], "verbose") == 0 ) {
newVerbosity = XR_VERBOSITY_VERBOSE;
} else if( strcmpcase(argv[1], "quiet") == 0 ) {
newVerbosity = XR_VERBOSITY_QUIET;
} else if( strcmpcase(argv[1], "normal") == 0 ) {
newVerbosity = XR_VERBOSITY_NORMAL;
} else if( (newVerbosity = atoi(argv[1])) >= 0 ) {
;
} else {
goto Bad;
}
break;
default:
goto Bad;
}
oldVerbosity = *(clce->clce_msgVerbosityP);
if( myRealName[0] == 'g' ) {
XR_verbosity = newVerbosity;
XR_CLLogMsg "global ");
}
*(clce->clce_msgVerbosityP) = newVerbosity;
XR_CLLogMsg "verbosity set to %d (was %d)\n",
newVerbosity, oldVerbosity);
return 1;
Bad:
XR_CLErrorMsg "%s arg: [verbosity_level]\n", argv[0]);
return (-1);
}
/*
* Start the world
*/
static struct XR_MLRep XR_packageInstallationLock;
static bool XR_packageInstalled = FALSE;
static
XR_CLPROC(XR_CLProc_install_and_run_package)
{
bool notMyProblem;
extern void XR_InstallAndRunPackage();
extern char XR_packageVersion[];
XR_MonitorEntry(&XR_packageInstallationLock);
notMyProblem = XR_packageInstalled;
XR_packageInstalled = TRUE;
XR_MonitorExit(&XR_packageInstallationLock);
if( notMyProblem ) {
XR_CLWarningMsg "%s: (do not use)\n", argv[0]);
return 1;
} else {
XR_CLLogMsg "initializing pkg version %s ...\n", XR_packageVersion);
XR_InstallAndRunPackage();
XR_CLLogMsg " ... package initialized\n");
return 1;
}
}
/*
* quit the world ...
*/
static
XR_CLPROC(XR_CLProc_quit)
{
XR_CLNormalMsg "good-bye\n");
XR_ExitWorld( (argc > 1) ? atoi(argv[1]) : 0 );
}
/*
* The amazing copywrite message ...
*/
char *(XR_copyrightMessageLines[]) = {
"Copyright (c) 1988, 1989, 1990 Xerox Corporation. All rights reserved.",
"Use and copying of this software and preparation of derivative works based",
"upon this software are permitted. Any distribution of this software or",
"derivative works must comply with all applicable United States export",
"control laws. This software is made available AS IS, and Xerox Corporation",
"makes no warranty about the software, its performance or its conformity to",
"any specification. Any person obtaining a copy of this software is requested",
"to send their name and post office or electronic mail address to",
"PCRCoordinator.pa@xerox.com, or",
"\tPCR Coordinator",
"\tXerox PARC",
"\t3333 Coyote Hill Rd.",
"\tPalo Alto, CA 94304",
NIL
};
static
XR_CLPROC(XR_CLProc_copyright)
{
char **p;
extern char XR_threadsVersion[];
XR_CLMsg "\nXerox Portable Common Runtime (PCR)\n");
XR_CLMsg "Version %s\n\n", XR_threadsVersion);
for( p = XR_copyrightMessageLines; *p != NIL; p++ ) {
XR_CLMsg "%s\n", *p );
}
XR_CLMsg "\n");
return 1;
}
/*
* Help facility
*/
static bool
XR_PrintOneHelpMessage(r, self)
XR_CLRegistration r;
XR_MesaProc self;
{
XR_CLCallEnv clce = (XR_CLCallEnv)(self->mp_x);
char *key;
char *helpMsg;
if( r == NIL ) XR_Panic("XR_PrintOneHelpMessage");
XR_CLGetRegistrationDetails(r, &key, NIL, &helpMsg, NIL, NIL);
if( helpMsg != NIL ) { XR_CLMsg " %s %s\n", key, helpMsg); }
return TRUE;
}
static
XR_CLPROC(XR_CLProc_help)
{
XR_MesaProc printProc;
XR_CLRegistration r;
int i;
printProc = XR_MakeMesaProc(
((XR_UntypedProc)(XR_PrintOneHelpMessage)),
((XR_Pointer)(clce)) );
if( argc <= 1 ) {
XR_CLMsg "Registered commands:\n\n");
XR_CLEnumerateRegistrations( clce->clce_pH, printProc );
XR_CLMsg "\n");
return 1;
}
for( i = 1; i < argc; i++ ) {
r = XR_CLGetRegistrationWithKey( clce->clce_pH, argv[i] );
if( r != NIL ) {
(void) XR_PrintOneHelpMessage(r, printProc);
} else {
XR_CLMsg " %s not registered\n", argv[i]);
}
}
return 1;
}
/*
* generic proc to set file name string
*/
static int
XR_SetFileName(fn, buf, bufLen, bufp)
char *fn;
char *buf;
int bufLen;
char **bufp;
{
int fnLen;
char *cwd;
int cwdLen;
extern char *getenv();
if( fn == NIL ) {
*bufp = NIL;
return 0;
}
fnLen = strlen(fn);
if( fn[0] == '/' ) {
if( fnLen >= bufLen ) {
return (-1);
}
strcpy( buf, fn );
*bufp = buf;
return 0;
}
cwd = getenv("PWD");
if( cwd == NIL ) {
return (-1);
}
cwdLen = strlen(cwd);
if( (cwdLen + fnLen + 1) >= bufLen ) {
return (-1);
}
strcpy( buf, cwd );
buf[cwdLen] = '/';
strcpy( buf+cwdLen+1, fn );
*bufp = buf;
return 0;
}
/*
* pcr file name -- for internalizing symbols, set during initialization
*/
static char XR_pcrFileNameBuf[256] = "./pcr"; /* hah! */
static char *XR_pcrFileName = NIL;
int
XR_SetPCRFileName(fn)
char *fn;
{
return XR_SetFileName(fn, XR_pcrFileNameBuf,
(sizeof XR_pcrFileNameBuf), &XR_pcrFileName );
}
char *
XR_GetPCRFileName()
{
return XR_pcrFileName;
}
/*
* temp directory -- may be set during initialization
*/
static char XR_tmpDirectoryBuf[256] = XR_DEFAULT_TMP_DIRECTORY;
static char *XR_tmpDirectory = XR_tmpDirectoryBuf;
int
XR_SetTmpDirectory(d)
char *d;
{
return XR_SetFileName(d, XR_tmpDirectoryBuf,
(sizeof XR_tmpDirectoryBuf), &XR_tmpDirectory );
}
char *
XR_GetTmpDirectory()
{
return XR_tmpDirectory;
}
char *
XR_get_loader_directory() /* OBSOLESCENT */
{
return XR_GetTmpDirectory();
}
/*
* dbxscript file name -- set during initialization
*/
static char XR_nameOfDBXScriptBuf[256] = XR_DEFAULT_DBX_SCRIPT_NAME;
static char *XR_nameOfDBXScript = XR_nameOfDBXScriptBuf;
int
XR_SetDBXScriptName(n)
char *n;
{
return XR_SetFileName(n, XR_nameOfDBXScriptBuf,
(sizeof XR_nameOfDBXScriptBuf), &XR_nameOfDBXScript );
}
char *
XR_GetDBXScriptName()
{
return XR_nameOfDBXScript;
}
/*
* Comand registration
*/
static char *(XR_clProcDescriptions[]) = {
(char *)XR_CLProc_help, NIL,
"[cmdname ...] -- print help messages",
"help", "?", NIL,
(char *)XR_CLProc_quit, NIL,
" -- quit pcr",
"quit", "exit", NIL,
(char *)XR_CLProc_msgs, "quiet",
"['quiet'|'normal'|'verbose'|level] -- set quiet mode",
"quiet", NIL,
(char *)XR_CLProc_msgs, "verbose",
"['verbose'|'normal'|'quiet'|level] -- set verbose mode",
"verbose", NIL,
(char *)XR_CLProc_msgs, "msgs",
"['normal'|'quiet'|'verbose'|level] -- set msg mode",
"msgs", NIL,
(char *)XR_CLProc_msgs, "global_msgs",
"['normal'|'quiet'|'verbose'|level] -- set msg mode",
"global_msgs", NIL,
(char *)XR_CLProc_load, "load_files",
"[-ppatchsize] filename ... -- load object files",
"load", "load_files", "nolibload_files", NIL,
(char *)XR_CLProc_unixload, NIL,
"[-ppatchsize] filename -- load_files filename ; call _XR_run_<name> or _XR_run",
"unixload", "uload", NIL,
(char *)XR_CLProc_call, "call",
"procname [arg ...] -- call proc in current file",
"call", NIL,
(char *)XR_CLProc_call, "callall",
"procname [arg ...] -- call proc",
"callall", NIL,
(char *)XR_CLProc_call_procs, "call_procs",
"procname ... -- call procs in current file, no args",
"call_procs", NIL,
(char *)XR_CLProc_call_procs, "callall_procs",
"procname ... -- call procs, no args",
"callall_procs", NIL,
(char *)XR_CLProc_atSign, NIL,
"[filename] -- include commands from named file or stdin",
"@", "include", NIL,
(char *)XR_CLProc_copyright, NIL,
" -- print copyright message",
"copyright", NIL,
(char *)XR_CLProc_install_and_run_package, NIL,
" -- (do not use)",
"install_and_run_package", NIL,
NIL
};
void
XR_SetupCommandLoop()
{
int registerAns;
XR_globalCLProcsHandle = XR_CLCreateProcsHandle();
if( XR_globalCLProcsHandle == NIL ) {
XR_Panic("SetupCommandLoop 0");
}
registerAns = XR_CLUnsafeRegisterProcs(
XR_globalCLProcsHandle, XR_clProcDescriptions );
if( registerAns < 0 ) {
XR_Panic("SetupCommandLoop 1");
}
}
static void
XR_CreateDBXScript(scriptName)
char *scriptName;
{
char infoFileName[256];
int pid;
XR_Fildes fd;
XR_ILGetInfoFileName(infoFileName);
pid = XR_GetPID();
fd = XR_Open(scriptName, (O_CREAT|O_WRONLY|O_TRUNC), 0777);
if( fd == XR_nullFildes ) {
XR_WarningVMsg "Cannot create %s\n", scriptName);
return;
}
XR_FPrintF(fd,
"# PCR debugging initialization file to be sourced by XrDBX.\n");
XR_FPrintF(fd,
"set core = %d\n", pid);
XR_FPrintF(fd,
"set model = %s\n", infoFileName);
(void) XR_Close(fd);
XR_NormalVMsg "%s installed.\n", scriptName);
}
static void
XR_MakeGlobalCLHandle()
{
int pkgArgc;
char **pkgArgv;
int pos0, lim0, pos1, lim1, posCL, limCL;
XR_CLHandle h;
int ans;
XR_GetPackageDefaultArgs(&pkgArgc, &pkgArgv);
for( pos0 = 0; pos0 < pkgArgc; pos0++ ) {
if( strcmp(pkgArgv[pos0], "--") == 0 ) break;
}
pos0 += 1;
for( lim0 = pos0; lim0 < pkgArgc; lim0++ ) {
if( strcmp(pkgArgv[lim0], "--") == 0 ) break;
}
pos1 = lim0 + 1;
lim1 = pkgArgc;
for( posCL = 1; posCL < XR_argc; posCL++ ) {
if( strcmp(XR_argv[posCL], "--") == 0 ) break;
}
posCL += 1;
limCL = XR_argc;
h = XR_CLCreateHandleFromArgs(0, NIL, NIL);
if( h == NIL ) XR_Panic("MakeGlobalCLHandle 0");
if( pos1 < lim1 ) {
ans = XR_CLPrependArgsToHandle(
h, (lim1 - pos1), (pkgArgv + pos1) );
if( ans < 0 ) XR_Panic("MakeGlobalCLHandle 1");
}
if( posCL < limCL ) {
ans = XR_CLPrependArgsToHandle(
h, (limCL - posCL), (XR_argv + posCL) );
if( ans < 0 ) XR_Panic("MakeGlobalCLHandle 2");
}
if( pos0 < lim0 ) {
ans = XR_CLPrependArgsToHandle(
h, (lim0 - pos0), (pkgArgv + pos0) );
if( ans < 0 ) XR_Panic("MakeGlobalCLHandle 3");
}
XR_globalCLHandle = h;
}
static int
XR_ProcessCommandLineArguments()
{
struct XR_PrePostProcDataRep pppd;
struct XR_CLCallEnvRep clce;
XR_CLCallEnv clceOld;
int result;
pppd.pppd_echoing = FALSE;
pppd.pppd_abortOnError = TRUE;
clce.clce_h = XR_globalCLHandle;
clce.clce_pH = XR_globalCLProcsHandle;
clce.clce_msgSink = XR_stdOutCLMsgSink;
clce.clce_msgVerbosityP = &XR_verbosity;
clce.clce_handlerProc = NIL;
clce.clce_clientData = (XR_Pointer)(&pppd);
clceOld = XR_SetTopLevelCLCallEnv(&clce);
result = XR_CLApply( &clce, &XR_preprocDefault, &XR_postprocDefault );
(void) XR_SetTopLevelCLCallEnv(clceOld);
return result;
}
void
XR_StartMainXR ()
{
char *tmpStr;
if( (tmpStr = XR_GetPCRFileName()) != NIL )
(void) init_dyload(tmpStr, FALSE, FALSE);
if( (tmpStr = XR_GetDBXScriptName()) != NIL )
XR_CreateDBXScript(tmpStr);
XR_MakeGlobalCLHandle();
(void)XR_ProcessCommandLineArguments();
XR_WarningVMsg "PCR returns from XR_Start. Terminating.\n");
XR_ExitWorld(0);
}